/**
 *	7.修改问题6中的array_offset函数，使它访问以列主序存储的伪数组，也就是最左边的下标率先变化。
 *	这个新函数，array_offset2,在其它方面应该与原先那个函数一样，计算这些数组下标的公式如下所示。
 *	对于一维伪数组:
 *		loc = s1 - lo1
 *	对于二维伪数组：
 *		loc = (s2 - lo2) × (hi1 - lo1 + 1) + s1 - lo1
 *	对于三维伪数组：
 *		loc = [(s3 - lo3) × (hi2 - lo2 + 1) + s2 - lo2] × (hi1 - lo1 + 1) + s1 - lo1
 *	对于四维伪数组：
 *		loc = [[(s4 - lo4) × (hi3 - lo3 + 1) + s3 - lo3] × (hi2 - lo2 + 1) + s2 - lo2] × (hi1 - lo1 + 1) + s1 - lo1
 *	
 *	举例：假定arrayinfo包含值2,4,6,1,5,-3,3.这些值提示我们所处理的是三维伪数组，第一个下标范围从4到6,
 *	第二个下标范围从1到5,第三个下标范围从-3到3,在这个例子中，array_offset被调用时将有三个下标参数传递给它，
 *	下面显示了几组下标值以及它们所代表的偏移量：
 *	subscripts		offset		subscripts		offset		subscripts		offset
 *	4,1,-3			0			4,2,-3			3			4,1,-1			30
 *	5,1,-3			1			4,3,-3			6			5,3,-1			37
 *	6,1,-3			2			4,1,-2			15			6,5,3			104
**/

#include <stdio.h>
#include <stdarg.h>

int array_offset(int arrayinfo[], ...);

int main()
{
	int arr[] = {2,4,6,1,5,-3,3};

	printf("offset = %d\n", array_offset(arr, 4, 1, -3));
	
	return 0;
}

int array_offset(int arrayinfo[], ...)
{
	int ndim;
	int offset;
	int hi, lo;
	int i;
	int s[10];
	int *sp;
	va_list subscripts;
	va_start(subscripts, arrayinfo);
	ndim = *arrayinfo++;
	arrayinfo += ndim * 2;
	sp = s + ndim;
	if(ndim >= 1 && ndim <= 10)
	{
		for(i = 0; i < ndim; i += 1)
			s[i] = va_arg(subscripts, int);
		va_end(subscripts);

		offset = 0;
		while(ndim >= 1)
		{
			hi = *--arrayinfo;
			lo = *--arrayinfo;
			if(*--sp > hi || *sp < lo)
				return -1;
			offset *= hi - lo + 1;
			offset += *sp - lo;
		}
		return offset;
	}
	return -1;
}
